/**
 * 卦象数据模型类
 */
class Hexagram {
	constructor({
		name,
		upperSymbol,
		lowerSymbol,
		description,
		upperElement,
		lowerElement
	}) {
		this.name = name;
		this.upperSymbol = upperSymbol;
		this.lowerSymbol = lowerSymbol;
		this.description = description;
		this.upperElement = upperElement;
		this.lowerElement = lowerElement;
	}

	/**
	 * 获取完整的卦象符号
	 */
	get fullSymbol() {
		return this.upperSymbol + this.lowerSymbol;
	}

	/**
	 * 获取五行相生相克关系
	 */
	get elementRelation() {
		// 五行相生相克关系表
		const relations = {
			'金': { '金': '比和', '木': '克制', '水': '生发', '火': '受克', '土': '受生' },
			'木': { '金': '受克', '木': '比和', '水': '受生', '火': '生发', '土': '克制' },
			'水': { '金': '受生', '木': '生发', '水': '比和', '火': '克制', '土': '受克' },
			'火': { '金': '克制', '木': '受生', '水': '受克', '火': '比和', '土': '生发' },
			'土': { '金': '生发', '木': '受克', '水': '克制', '火': '受生', '土': '比和' }
		};

		if (relations[this.upperElement] && relations[this.upperElement][this.lowerElement]) {
			return relations[this.upperElement][this.lowerElement];
		}

		return '未知关系';
	}

	/**
	 * 转换为对象
	 */
	toObject() {
		return {
			name: this.name,
			upperSymbol: this.upperSymbol,
			lowerSymbol: this.lowerSymbol,
			description: this.description,
			upperElement: this.upperElement,
			lowerElement: this.lowerElement
		};
	}

	/**
	 * 从对象创建卦象实例
	 */
	static fromObject(obj) {
		return new Hexagram({
			name: obj.name,
			upperSymbol: obj.upperSymbol,
			lowerSymbol: obj.lowerSymbol,
			description: obj.description,
			upperElement: obj.upperElement,
			lowerElement: obj.lowerElement
		});
	}
}

/**
 * 卦象服务类 - 处理各种起卦方式
 */
class HexagramService {
	constructor() {
		// 导入API服务
		this.apiService = require('./api-service.js').default;
		this.init();
	}

	init() {
		// 八卦基本数据
		this.basicHexagrams = {
			'乾': { symbol: '☰', nature: '天', element: '金' },
			'坤': { symbol: '☷', nature: '地', element: '土' },
			'震': { symbol: '☳', nature: '雷', element: '木' },
			'巽': { symbol: '☴', nature: '风', element: '木' },
			'坎': { symbol: '☵', nature: '水', element: '水' },
			'离': { symbol: '☲', nature: '火', element: '火' },
			'艮': { symbol: '☶', nature: '山', element: '土' },
			'兑': { symbol: '☱', nature: '泽', element: '金' }
		};

		// 六十四卦数据
		this.hexagramData = [
			{ name: '乾为天', upper: '乾', lower: '乾', description: '天行健，君子以自强不息' },
			{ name: '坤为地', upper: '坤', lower: '坤', description: '地势坤，君子以厚德载物' },
			{ name: '水雷屯', upper: '坎', lower: '震', description: '云雷屯，君子以经纶' },
			{ name: '山水蒙', upper: '艮', lower: '坎', description: '山下出泉，蒙；君子以果行育德' },
			{ name: '水天需', upper: '坎', lower: '乾', description: '云上于天，需；君子以饮食宴乐' },
			{ name: '天水讼', upper: '乾', lower: '坎', description: '天与水违行，讼；君子以作事谋始' },
			{ name: '地水师', upper: '坤', lower: '坎', description: '地中有水，师；君子以容民畜众' },
			{ name: '水地比', upper: '坎', lower: '坤', description: '地上有水，比；先王以建万国，亲诸侯' },
			{ name: '风天小畜', upper: '巽', lower: '乾', description: '风行天上，小畜；君子以懿文德' },
			{ name: '天泽履', upper: '乾', lower: '兑', description: '上天下泽，履；君子以辨上下，定民志' },
			{ name: '地天泰', upper: '坤', lower: '乾', description: '天地交，泰；后以财成天地之道，辅相天地之宜，以左右民' },
			{ name: '天地否', upper: '乾', lower: '坤', description: '天地不交，否；君子以俭德辟难，不可荣以禄' },
			{ name: '天火同人', upper: '乾', lower: '离', description: '天与火，同人；君子以类族辨物' },
			{ name: '火天大有', upper: '离', lower: '乾', description: '火在天上，大有；君子以遏恶扬善，顺天休命' },
			{ name: '地山谦', upper: '坤', lower: '艮', description: '地中有山，谦；君子以裒多益寡，称物平施' },
			{ name: '雷地豫', upper: '震', lower: '坤', description: '雷出地奋，豫；先王以作乐崇德，殷荐之上帝，以配祖考' },
			{ name: '泽雷随', upper: '兑', lower: '震', description: '泽中有雷，随；君子以向晦入宴息' },
			{ name: '山风蛊', upper: '艮', lower: '巽', description: '山下有风，蛊；君子以振民育德' },
			{ name: '地泽临', upper: '坤', lower: '兑', description: '泽上有地，临；君子以教思无穷，容保民无疆' },
			{ name: '风地观', upper: '巽', lower: '坤', description: '风行地上，观；先王以省方观民设教' },
			{ name: '火雷噬嗑', upper: '离', lower: '震', description: '雷电噬嗑；先王以明罚敕法' },
			{ name: '山火贲', upper: '艮', lower: '离', description: '山下有火，贲；君子以明庶政，无敢折狱' },
			{ name: '山地剥', upper: '艮', lower: '坤', description: '山附于地，剥；上以厚下，安宅' },
			{ name: '地雷复', upper: '坤', lower: '震', description: '雷在地中，复；先王以至日闭关，商旅不行，后不省方' },
			{ name: '天雷无妄', upper: '乾', lower: '震', description: '天下雷行，物与无妄；先王以茂对时育万物' },
			{ name: '山天大畜', upper: '艮', lower: '乾', description: '天在山中，大畜；君子以多识前言往行，以畜其德' },
			{ name: '山雷颐', upper: '艮', lower: '震', description: '山下有雷，颐；君子以慎言语，节饮食' },
			{ name: '泽风大过', upper: '兑', lower: '巽', description: '泽灭木，大过；君子以独立不惧，遁世无闷' },
			{ name: '坎为水', upper: '坎', lower: '坎', description: '水洊至，习坎；君子以常德行，习教事' },
			{ name: '离为火', upper: '离', lower: '离', description: '明两作，离；大人以继明照于四方' },
			{ name: '泽山咸', upper: '兑', lower: '艮', description: '山上有泽，咸；君子以虚受人' },
			{ name: '雷风恒', upper: '震', lower: '巽', description: '雷风，恒；君子以立不易方' },
			{ name: '天山遁', upper: '乾', lower: '艮', description: '天下有山，遁；君子以远小人，不恶而严' },
			{ name: '雷天大壮', upper: '震', lower: '乾', description: '雷在天上，大壮；君子以非礼弗履' },
			{ name: '火地晋', upper: '离', lower: '坤', description: '明出地上，晋；君子以自昭明德' },
			{ name: '地火明夷', upper: '坤', lower: '离', description: '明入地中，明夷；君子以莅众，用晦而明' },
			{ name: '风火家人', upper: '巽', lower: '离', description: '风自火出，家人；君子以言有物，而行有恒' },
			{ name: '火泽睽', upper: '离', lower: '兑', description: '上火下泽，睽；君子以同而异' },
			{ name: '水山蹇', upper: '坎', lower: '艮', description: '山上有水，蹇；君子以反身修德' },
			{ name: '雷水解', upper: '震', lower: '坎', description: '雷雨作，解；君子以赦过宥罪' },
			{ name: '山泽损', upper: '艮', lower: '兑', description: '山下有泽，损；君子以惩忿窒欲' },
			{ name: '风雷益', upper: '巽', lower: '震', description: '风雷，益；君子以见善则迁，有过则改' },
			{ name: '泽天夬', upper: '兑', lower: '乾', description: '泽上于天，夬；君子以施禄及下，居德则忌' },
			{ name: '天风姤', upper: '乾', lower: '巽', description: '天下有风，姤；后以施命诰四方' },
			{ name: '泽地萃', upper: '兑', lower: '坤', description: '泽上于地，萃；君子以除戎器，戒不虞' },
			{ name: '地风升', upper: '坤', lower: '巽', description: '地中生木，升；君子以顺德，积小以高大' },
			{ name: '泽水困', upper: '兑', lower: '坎', description: '泽无水，困；君子以致命遂志' },
			{ name: '水风井', upper: '坎', lower: '巽', description: '木上有水，井；君子以劳民劝相' },
			{ name: '泽火革', upper: '兑', lower: '离', description: '泽中有火，革；君子以治历明时' },
			{ name: '火风鼎', upper: '离', lower: '巽', description: '木上有火，鼎；君子以正位凝命' },
			{ name: '震为雷', upper: '震', lower: '震', description: '洊雷，震；君子以恐惧修省' },
			{ name: '艮为山', upper: '艮', lower: '艮', description: '兼山，艮；君子以思不出其位' },
			{ name: '风山渐', upper: '巽', lower: '艮', description: '山上有木，渐；君子以居贤德善俗' },
			{ name: '雷泽归妹', upper: '震', lower: '兑', description: '泽上有雷，归妹；君子以永终知敝' },
			{ name: '雷火丰', upper: '震', lower: '离', description: '雷电皆至，丰；君子以折狱致刑' },
			{ name: '火山旅', upper: '离', lower: '艮', description: '山上有火，旅；君子以明慎用刑，而不留狱' },
			{ name: '巽为风', upper: '巽', lower: '巽', description: '随风，巽；君子以申命行事' },
			{ name: '兑为泽', upper: '兑', lower: '兑', description: '丽泽，兑；君子以朋友讲习' },
			{ name: '风水涣', upper: '巽', lower: '坎', description: '风行水上，涣；先王以享于帝，立庙' },
			{ name: '水泽节', upper: '坎', lower: '兑', description: '泽上有水，节；君子以制数度，议德行' },
			{ name: '风泽中孚', upper: '巽', lower: '兑', description: '泽上有风，中孚；君子以议狱缓死' },
			{ name: '雷山小过', upper: '震', lower: '艮', description: '山上有雷，小过；君子以行过乎恭，丧过乎哀，用过乎俭' },
			{ name: '水火既济', upper: '坎', lower: '离', description: '水在火上，既济；君子以思患而豫防之' },
			{ name: '火水未济', upper: '离', lower: '坎', description: '火在水上，未济；君子以慎辨物居方' }
		];
	}

	/**
	 * 根据时间生成卦象（调用后端API）
	 */
	async generateFromTime(time) {
		try {
			const response = await this.apiService.timeDivination({
				question: '今日运势',
				useCurrentTime: true,
				divinationTime: time.toISOString()
			});
			
			if (response.success && response.data && response.data.hexagram) {
				const hexagramData = response.data.hexagram;
				return new Hexagram({
					name: hexagramData.name,
					upperSymbol: hexagramData.upperTrigram?.symbol || '',
					lowerSymbol: hexagramData.lowerTrigram?.symbol || '',
					description: hexagramData.hexagramText || '',
					upperElement: hexagramData.upperTrigram?.element || '',
					lowerElement: hexagramData.lowerTrigram?.element || ''
				});
			} else {
				// 如果API调用失败，使用本地生成作为备选
				return this._generateLocalFromTime(time);
			}
		} catch (error) {
			console.error('调用后端时间起卦API失败，使用本地生成:', error);
			// 如果API调用失败，使用本地生成作为备选
			return this._generateLocalFromTime(time);
		}
	}

	/**
	 * 根据数字生成卦象（调用后端API）
	 */
	async generateFromNumbers(number1, number2) {
		try {
			const response = await this.apiService.numberDivination({
				question: '数字起卦',
				numbers: [number1, number2]
			});
			
			if (response.success && response.data && response.data.hexagram) {
				const hexagramData = response.data.hexagram;
				return new Hexagram({
					name: hexagramData.name,
					upperSymbol: hexagramData.upperTrigram?.symbol || '',
					lowerSymbol: hexagramData.lowerTrigram?.symbol || '',
					description: hexagramData.hexagramText || '',
					upperElement: hexagramData.upperTrigram?.element || '',
					lowerElement: hexagramData.lowerTrigram?.element || ''
				});
			} else {
				// 如果API调用失败，使用本地生成作为备选
				return this._generateLocalFromNumbers(number1, number2);
			}
		} catch (error) {
			console.error('调用后端数字起卦API失败，使用本地生成:', error);
			// 如果API调用失败，使用本地生成作为备选
			return this._generateLocalFromNumbers(number1, number2);
		}
	}

	/**
	 * 根据文本生成卦象（调用后端API）
	 */
	async generateFromText(text) {
		try {
			const response = await this.apiService.textDivination({
				question: '文本起卦',
				inputText: text
			});
			
			if (response.success && response.data && response.data.hexagram) {
				const hexagramData = response.data.hexagram;
				return new Hexagram({
					name: hexagramData.name,
					upperSymbol: hexagramData.upperTrigram?.symbol || '',
					lowerSymbol: hexagramData.lowerTrigram?.symbol || '',
					description: hexagramData.hexagramText || '',
					upperElement: hexagramData.upperTrigram?.element || '',
					lowerElement: hexagramData.lowerTrigram?.element || ''
				});
			} else {
				// 如果API调用失败，使用本地生成作为备选
				return this._generateLocalFromText(text);
			}
		} catch (error) {
			console.error('调用后端文本起卦API失败，使用本地生成:', error);
			// 如果API调用失败，使用本地生成作为备选
			return this._generateLocalFromText(text);
		}
	}

	/**
	 * 本地时间起卦（备选方案）
	 */
	_generateLocalFromTime(time) {
		const date = new Date(time);
		// 使用时间的小时、分钟、秒数作为种子
		const seed = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
		
		// 使用简单的线性同余生成器创建伪随机数
		const random = this._createSeededRandom(seed);
		
		// 随机选择一个卦象
		const index = Math.floor(random() * this.hexagramData.length);
		const hexagramInfo = this.hexagramData[index];
		
		const upperHexagram = hexagramInfo.upper;
		const lowerHexagram = hexagramInfo.lower;
		
		return new Hexagram({
			name: hexagramInfo.name,
			upperSymbol: this.basicHexagrams[upperHexagram]?.symbol || '',
			lowerSymbol: this.basicHexagrams[lowerHexagram]?.symbol || '',
			description: hexagramInfo.description,
			upperElement: this.basicHexagrams[upperHexagram]?.element || '',
			lowerElement: this.basicHexagrams[lowerHexagram]?.element || ''
		});
	}

	/**
	 * 本地数字起卦（备选方案）
	 */
	_generateLocalFromNumbers(number1, number2) {
		// 确保数字在有效范围内
		number1 = ((number1 - 1) % 8) + 1;
		number2 = ((number2 - 1) % 8) + 1;
		
		// 映射到八卦
		const bagua = Object.keys(this.basicHexagrams);
		const upperHexagram = bagua[number1 - 1];
		const lowerHexagram = bagua[number2 - 1];
		
		// 查找对应的六十四卦
		let hexagramInfo = this.hexagramData.find(hexagram => 
			hexagram.upper === upperHexagram && hexagram.lower === lowerHexagram
		);
		
		// 如果没有找到匹配的卦象，使用默认值
		if (!hexagramInfo) {
			hexagramInfo = this.hexagramData[0];
		}
		
		return new Hexagram({
			name: hexagramInfo.name,
			upperSymbol: this.basicHexagrams[upperHexagram]?.symbol || '',
			lowerSymbol: this.basicHexagrams[lowerHexagram]?.symbol || '',
			description: hexagramInfo.description,
			upperElement: this.basicHexagrams[upperHexagram]?.element || '',
			lowerElement: this.basicHexagrams[lowerHexagram]?.element || ''
		});
	}

	/**
	 * 本地文本起卦（备选方案）
	 */
	_generateLocalFromText(text) {
		// 使用文本的哈希值作为种子
		const seed = this._hashCode(text);
		const random = this._createSeededRandom(seed);
		
		const index = Math.floor(random() * this.hexagramData.length);
		const hexagramInfo = this.hexagramData[index];
		
		const upperHexagram = hexagramInfo.upper;
		const lowerHexagram = hexagramInfo.lower;
		
		return new Hexagram({
			name: hexagramInfo.name,
			upperSymbol: this.basicHexagrams[upperHexagram]?.symbol || '',
			lowerSymbol: this.basicHexagrams[lowerHexagram]?.symbol || '',
			description: hexagramInfo.description,
			upperElement: this.basicHexagrams[upperHexagram]?.element || '',
			lowerElement: this.basicHexagrams[lowerHexagram]?.element || ''
		});
	}

	/**
	 * 获取所有卦象数据（调用后端API）
	 */
	async getAllHexagrams() {
		try {
			const response = await this.apiService.getAllHexagrams();
			
			if (response.success && response.data && response.data.hexagrams) {
				return response.data.hexagrams.map(hexagram => {
					return new Hexagram({
						name: hexagram.name,
						upperSymbol: hexagram.upperTrigram?.symbol || '',
						lowerSymbol: hexagram.lowerTrigram?.symbol || '',
						description: hexagram.hexagramText || '',
						upperElement: hexagram.upperTrigram?.element || '',
						lowerElement: hexagram.lowerTrigram?.element || ''
					});
				});
			} else {
				// 如果API调用失败，使用本地数据作为备选
				return this._getAllLocalHexagrams();
			}
		} catch (error) {
			console.error('调用后端获取六十四卦API失败，使用本地数据:', error);
			// 如果API调用失败，使用本地数据作为备选
			return this._getAllLocalHexagrams();
		}
	}

	/**
	 * 获取本地所有卦象数据（备选方案）
	 */
	_getAllLocalHexagrams() {
		return this.hexagramData.map(hexagram => {
			const upperHexagram = hexagram.upper;
			const lowerHexagram = hexagram.lower;
			
			return new Hexagram({
				name: hexagram.name,
				upperSymbol: this.basicHexagrams[upperHexagram]?.symbol || '',
				lowerSymbol: this.basicHexagrams[lowerHexagram]?.symbol || '',
				description: hexagram.description,
				upperElement: this.basicHexagrams[upperHexagram]?.element || '',
				lowerElement: this.basicHexagrams[lowerHexagram]?.element || ''
			});
		});
	}

	/**
	 * 创建基于种子的随机数生成器
	 */
	_createSeededRandom(seed) {
		let value = seed;
		return function() {
			value = (value * 9301 + 49297) % 233280;
			return value / 233280;
		};
	}

	/**
	 * 计算字符串的哈希值
	 */
	_hashCode(str) {
		let hash = 0;
		if (str.length === 0) return hash;
		for (let i = 0; i < str.length; i++) {
			const char = str.charCodeAt(i);
			hash = ((hash << 5) - hash) + char;
			hash = hash & hash; // 转换为32位整数
		}
		return Math.abs(hash);
	}
}

export { HexagramService, Hexagram };
export default HexagramService;